import { cloneDeep } from 'lodash-es';
import type { RouteRecordRaw } from 'vue-router';
import useSettingsStore from './settings';
import { resolveRoutePath } from '@/utils';
import { systemRoutes } from '@/router/routes';
import type { Route } from '#/global';

const useRouteStore = defineStore(
  // 唯一ID
  'route',
  () => {
    const settingsStore = useSettingsStore();

    const isGenerate = ref(false);
    const routesRaw = ref<Route.recordMainRaw[]>([]);
    const filesystemRoutesRaw = ref<RouteRecordRaw[]>([]);
    const currentRemoveRoutes = ref<(() => void)[]>([]);

    // 将多层嵌套路由处理成两层，保留顶层和最子层路由，中间层级将被拍平
    function flatAsyncRoutes<T extends RouteRecordRaw>(route: T): T {
      if (route.children) {
        route.children = flatAsyncRoutesRecursive(
          route.children,
          [
            {
              path: route.path,
              title: route.meta?.title,
              icon: route.meta?.icon,
              hide: !route.meta?.breadcrumb && route.meta?.breadcrumb === false,
            },
          ],
          route.path
        );
      }
      return route;
    }
    function flatAsyncRoutesRecursive(
      routes: RouteRecordRaw[],
      breadcrumb: Route.breadcrumb[] = [],
      baseUrl = ''
    ): RouteRecordRaw[] {
      const res: RouteRecordRaw[] = [];
      routes.forEach(route => {
        if (route.children) {
          const childrenBaseUrl = resolveRoutePath(baseUrl, route.path);
          const tmpBreadcrumb = cloneDeep(breadcrumb);
          tmpBreadcrumb.push({
            path: childrenBaseUrl,
            title: route.meta?.title,
            icon: route.meta?.icon,
            hide: !route.meta?.breadcrumb && route.meta?.breadcrumb === false,
          });
          const tmpRoute = cloneDeep(route);
          tmpRoute.path = childrenBaseUrl;
          if (!tmpRoute.meta) {
            tmpRoute.meta = {};
          }
          tmpRoute.meta.breadcrumbNeste = tmpBreadcrumb;
          delete tmpRoute.children;
          res.push(tmpRoute);
          const childrenRoutes = flatAsyncRoutesRecursive(
            route.children,
            tmpBreadcrumb,
            childrenBaseUrl
          );
          childrenRoutes.forEach(item => {
            // 如果 path 一样则覆盖，因为子路由的 path 可能设置为空，导致和父路由一样，直接注册会提示路由重复
            if (res.some(v => v.path === item.path)) {
              res.forEach((v, i) => {
                if (v.path === item.path) {
                  res[i] = item;
                }
              });
            } else {
              res.push(item);
            }
          });
        } else {
          const tmpRoute = cloneDeep(route);
          tmpRoute.path = resolveRoutePath(baseUrl, tmpRoute.path);
          // 处理面包屑导航
          const tmpBreadcrumb = cloneDeep(breadcrumb);
          tmpBreadcrumb.push({
            path: tmpRoute.path,
            title: tmpRoute.meta?.title,
            icon: tmpRoute.meta?.icon,
            hide:
              !tmpRoute.meta?.breadcrumb && tmpRoute.meta?.breadcrumb === false,
          });
          if (!tmpRoute.meta) {
            tmpRoute.meta = {};
          }
          tmpRoute.meta.breadcrumbNeste = tmpBreadcrumb;
          res.push(tmpRoute);
        }
      });
      return res;
    }
    // 扁平化路由（将三级及以上路由数据拍平成二级）
    const flatRoutes = computed(() => {
      const returnRoutes: RouteRecordRaw[] = [];

      if (settingsStore.settings.app.routeBaseOn !== 'filesystem') {
        if (routesRaw.value) {
          routesRaw.value.forEach(item => {
            const tmpRoutes = cloneDeep(item.children) as RouteRecordRaw[];
            tmpRoutes.map(v => {
              if (!v.meta) {
                v.meta = {};
              }
              v.meta.auth = item.meta?.auth ?? v.meta?.auth;
              return v;
            });
            returnRoutes.push(...tmpRoutes);
          });
          returnRoutes.forEach(item => flatAsyncRoutes(item));
        }
      } else {
        returnRoutes.push(
          ...(cloneDeep(filesystemRoutesRaw.value) as RouteRecordRaw[])
        );
      }
      return returnRoutes;
    });
    const flatSystemRoutes = computed(() => {
      const routes = [...systemRoutes];
      routes.forEach(item => flatAsyncRoutes(item));
      return routes;
    });

    // 生成路由（前端生成）
    function generateRoutesAtFront(asyncRoutes: Route.recordMainRaw[]) {
      // 设置 routes 数据
      routesRaw.value = cloneDeep(asyncRoutes) as any;
      isGenerate.value = true;
    }

    // 记录 accessRoutes 路由，用于登出时删除路由
    function setCurrentRemoveRoutes(routes: (() => void)[]) {
      currentRemoveRoutes.value = routes;
    }
    // 清空动态路由
    function removeRoutes() {
      isGenerate.value = false;
      routesRaw.value = [];
      filesystemRoutesRaw.value = [];
      currentRemoveRoutes.value.forEach(removeRoute => {
        removeRoute();
      });
      currentRemoveRoutes.value = [];
    }

    return {
      isGenerate,
      routesRaw,
      currentRemoveRoutes,
      flatRoutes,
      flatSystemRoutes,
      generateRoutesAtFront,
      setCurrentRemoveRoutes,
      removeRoutes,
    };
  }
);

export default useRouteStore;
